package com.example.texted;

import com.jcraft.jsch.*;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;

public class JschCmd {
    String ip = null;
    String priKeyBasePath = null;
    Session session = null;

    private static final JschCmd instance = new JschCmd();

    private JschCmd (){

    }

    public static JschCmd getInstance() {
        return instance;
    }

    public void init() throws JSchException, IOException {
        Properties properties = new Properties();
        properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties"));
        ip = properties.getProperty("ip");
        priKeyBasePath = properties.getProperty("priKeyBasePath");
        //建立JSch对象
        JSch jsch = new JSch();
        //添加私钥
        jsch.addIdentity(priKeyBasePath);
        session=jsch.getSession(ip);
        //SSH 公钥检查机制 no、ask、yes
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        System.out.println("连接成功！"+ip);
        System.out.println(session.isConnected());
    }

    public String doCmd(String cmd) throws JSchException, IOException {
        ChannelExec channelExec  = (ChannelExec) session.openChannel("exec");
        InputStream inputStream = channelExec.getInputStream();
        channelExec.setCommand(cmd);
        channelExec.setErrStream(System.err);
        System.out.println("开始执行："+cmd);
        channelExec.connect();
        System.out.println("执行完成："+cmd);
        System.out.println("返回结果："+cmd);
        String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
        inputStream.close();
        System.out.println("关闭inputStream");
        channelExec.disconnect();
        return result;
    }

    public void execCommandByShell(List<String> cmds)throws IOException,JSchException{

        ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
        InputStream inputStream = channelShell.getInputStream();//从远端到达的数据  都能从这个流读取到
        channelShell.setPty(true);
        channelShell.connect();

        OutputStream outputStream = channelShell.getOutputStream();//写入该流的数据  都将发送到远程端
        //使用PrintWriter 就是为了使用println 这个方法
        //好处就是不需要每次手动给字符加\n
        PrintWriter printWriter = new PrintWriter(outputStream);
        cmds.forEach(printWriter::println);
        printWriter.println("exit");//为了结束本次交互
        printWriter.flush();//把缓冲区的数据强行输出

        byte[] tmp = new byte[1024];
        while(true){

            while(inputStream.available() > 0){
                int i = inputStream.read(tmp, 0, 1024);
                if(i < 0) break;
                String s = new String(tmp, 0, i);
                if(s.contains("--More--")){
                    outputStream.write((" ").getBytes());
                    outputStream.flush();
                }
                System.out.println(s);
            }
            if(channelShell.isClosed()){
                System.out.println("exit-status:"+channelShell.getExitStatus());
                break;
            }
            try{
                Thread.sleep(1000);
            }catch(Exception ignored){

            }
        }
        outputStream.close();
        inputStream.close();
        channelShell.disconnect();
        System.out.println("DONE");
    }

    public void close(){
        System.out.println("开始关闭");
        if (session.isConnected()) {
            session.disconnect();
            System.out.println("关闭session");
        }
    }
}
